/* sv_funcs.c - TCPechod, TCPchargend, TCPdaytimed, TCPtimed */

#include <sys/types.h>

#include <unistd.h>
#include <time.h>

#include <sys/types.h>
#include <sys/param.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <sys/resource.h>
#include <sys/errno.h>
#include <sys/signal.h>
#include <sys/wait.h>
#include <netinet/in.h>

#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>

#define	BUFFERSIZE	4096		/* max read buffer size	*/

void	TCPechod(int), TCPdaytimed(int), UDPtimed(int);
int	errexit(const char *format, ...);

/*------------------------------------------------------------------------
 * TCPecho - do TCP ECHO on the given socket
 *------------------------------------------------------------------------
 */
void
TCPechod(int fd)
{
	char	buf[BUFFERSIZE];
	int	cc;

	while (cc = read(fd, buf, sizeof buf)) {
		if (cc < 0)
			errexit("echo read: %s\n", strerror(errno));
		if (write(fd, buf, cc) < 0)
			errexit("echo write: %s\n", strerror(errno));
	}
}

//-------------------------------
void
UDPechod(int fd)
{
	char buf[BUFFERSIZE];
	memset(buf,0,sizeof(buf));
	struct sockaddr_in fsin;
	int alen = sizeof(fsin);
	
	if (recvfrom(fd, buf, sizeof(buf), 0,
				(struct sockaddr *)&fsin, &alen) < 0)
			errexit("recvfrom: %s\n", strerror(errno));
		(void) sendto(fd, buf, sizeof(buf), 0,
			(struct sockaddr *)&fsin, sizeof(fsin));
}
//---------------------------------

#define	LINELEN		72


/*------------------------------------------------------------------------
 * TCPdaytimed - do TCP DAYTIME protocol
 *------------------------------------------------------------------------
 */
void
TCPdaytimed(int fd)
{
	char	buf[LINELEN], *ctime();
	time_t	now;

	(void) time(&now);
	sprintf(buf, "%s", ctime(&now));
	(void) write(fd, buf, strlen(buf));
}

#define	UNIXEPOCH	2208988800UL	/* UNIX epoch, in UCT secs	*/

/*------------------------------------------------------------------------
 * TCPtimed - do TCP TIME protocol
 *------------------------------------------------------------------------
 */
void
UDPtimed(int fd)
{
	char buf[LINELEN];
	time_t	now;
	struct sockaddr_in fsin;
	int alen = sizeof(fsin);
	
	if (recvfrom(fd, buf, sizeof(buf), 0,
				(struct sockaddr *)&fsin, &alen) < 0)
			errexit("recvfrom: %s\n", strerror(errno));
		(void) time(&now);
		now = htonl((unsigned long)(now + UNIXEPOCH));
		(void) sendto(fd, (char *)&now, sizeof(now), 0,
			(struct sockaddr *)&fsin, sizeof(fsin));
}
